package com.hamizhong.iflowers.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.springframework.beans.BeanUtils;

import com.hamizhong.iflowers.db.dao.hibernate.ICityDao;
import com.hamizhong.iflowers.db.dao.hibernate.ICommentDao;
import com.hamizhong.iflowers.db.dao.hibernate.IGoodsDao;
import com.hamizhong.iflowers.db.dao.hibernate.IOrdersDao;
import com.hamizhong.iflowers.db.dao.hibernate.IProvinceDao;
import com.hamizhong.iflowers.db.dao.hibernate.IUserDao;
import com.hamizhong.iflowers.db.entity.City;
import com.hamizhong.iflowers.db.entity.Comment;
import com.hamizhong.iflowers.db.entity.Goods;
import com.hamizhong.iflowers.db.entity.Orders;
import com.hamizhong.iflowers.db.entity.User;
import com.hamizhong.iflowers.service.IOrdersService;
import com.hamizhong.iflowers.service.base.MyBaseService;
import com.hamizhong.iflowers.utils.MyErrorMsgConstants;
import com.hamizhong.iflowers.web.dto.IOPResultDto;
import com.hamizhong.iflowers.web.vo.CityVO;
import com.hamizhong.iflowers.web.vo.CommentVO;
import com.hamizhong.iflowers.web.vo.GoodsVO;
import com.hamizhong.iflowers.web.vo.IObjectVO;
import com.hamizhong.iflowers.web.vo.OrdersVO;
import com.hamizhong.iflowers.web.vo.UserVO;

public class OrdersServiceImpl extends MyBaseService implements IOrdersService {
	
	private IOrdersDao iOrdersDao = null;
	private IProvinceDao iProvinceDao = null;
	private IGoodsDao iGoodsDao = null;
	private ICityDao iCityDao = null;
	private IUserDao iUserDao = null;
	private ICommentDao iCommentDao = null;
	
	public IOrdersDao getiOrdersDao() {
		return iOrdersDao;
	}
	public void setiOrdersDao(IOrdersDao iOrdersDao) {
		this.iOrdersDao = iOrdersDao;
	}
	public IProvinceDao getiProvinceDao() {
		return iProvinceDao;
	}
	public void setiProvinceDao(IProvinceDao iProvinceDao) {
		this.iProvinceDao = iProvinceDao;
	}
	public IGoodsDao getiGoodsDao() {
		return iGoodsDao;
	}
	public void setiGoodsDao(IGoodsDao iGoodsDao) {
		this.iGoodsDao = iGoodsDao;
	}
	public ICityDao getiCityDao() {
		return iCityDao;
	}
	public void setiCityDao(ICityDao iCityDao) {
		this.iCityDao = iCityDao;
	}
	public IUserDao getiUserDao() {
		return iUserDao;
	}
	public void setiUserDao(IUserDao iUserDao) {
		this.iUserDao = iUserDao;
	}
	public ICommentDao getiCommentDao() {
		return iCommentDao;
	}
	public void setiCommentDao(ICommentDao iCommentDao) {
		this.iCommentDao = iCommentDao;
	}
	
	public IOPResultDto<IObjectVO> addOrders(OrdersVO ordersVO) {
		IOPResultDto<IObjectVO> dto = new IOPResultDto<IObjectVO>();
		try {
			Orders orders = new Orders();
			BeanUtils.copyProperties(ordersVO, orders);
			Goods goods = iGoodsDao.findById(ordersVO.getGoodsVO().getGoodsId());
			City city = iCityDao.findById(ordersVO.getCityVO().getCityId());
			User user = iUserDao.findById(ordersVO.getUserVO().getUserId());
			orders.setGoods(goods);
			orders.setCity(city);
			orders.setUser(user);
			iOrdersDao.add(orders);
			dto.setSuccess(true);
		} catch (Exception e) {
			e.printStackTrace();
			dto.setErrorMSG(MyErrorMsgConstants.FAILED_TO_ADD_ORDERS);
			dto.setSuccess(false);
		}
		return dto;
	}
	
	public IOPResultDto<IObjectVO> findByUserId(Integer userId) {
		IOPResultDto<IObjectVO> dto = new IOPResultDto<IObjectVO>();
		try {
			User user = iUserDao.findById(userId);
			HashMap<String, Object> param = new HashMap<String, Object>();
			param.put("user", user);
			List<Orders> ordersList = iOrdersDao.findByExample(param);
			List<OrdersVO> ordersVOList = new ArrayList<OrdersVO>();
			OrdersVO ordersVO = null;
			Goods goods = null;
			GoodsVO goodsVO = null;
			for (Orders orders : ordersList) {
				goods = iGoodsDao.findById(orders.getGoods().getGoodsId());
				goodsVO = new GoodsVO();
				BeanUtils.copyProperties(goods, goodsVO);
				ordersVO = new OrdersVO();
				BeanUtils.copyProperties(orders, ordersVO);
				ordersVO.setGoodsVO(goodsVO);
				ordersVOList.add(ordersVO);
			}
			IObjectVO iObjectVO = new IObjectVO();
			iObjectVO.setOrdersVOList(ordersVOList);
			dto.addToResultList(iObjectVO);
			dto.setSuccess(true);
		} catch (Exception e) {
			e.printStackTrace();
			dto.setErrorMSG(MyErrorMsgConstants.FAILED_TO_QUERY_ORDERS);
			dto.setSuccess(false);
		}
		return dto;
	}
	
	public IOPResultDto<IObjectVO> findByStateAndUserId(Integer orderState, Integer userId, Integer pageNum, Integer pageSize) {
		IOPResultDto<IObjectVO> dto = new IOPResultDto<IObjectVO>();
		try {
			List<Orders> ordersList = iOrdersDao.findByStateAndUserId(orderState, userId, pageNum, pageSize);
			int totalOrdersCnt = iOrdersDao.findTotalOrdersCntByOrderStateAndUserId(orderState, userId);
			List<OrdersVO> ordersVOList = new ArrayList<OrdersVO>();
			OrdersVO ordersVO = null;
			Goods goods = null;
			GoodsVO goodsVO = null;
			for (Orders orders : ordersList) {
				goods = iGoodsDao.findById(orders.getGoods().getGoodsId());
				goodsVO = new GoodsVO();
				BeanUtils.copyProperties(goods, goodsVO);
				ordersVO = new OrdersVO();
				BeanUtils.copyProperties(orders, ordersVO);
				ordersVO.setGoodsVO(goodsVO);
				ordersVOList.add(ordersVO);
			}
			IObjectVO iObjectVO = new IObjectVO();
			iObjectVO.setOrdersVOList(ordersVOList);
			iObjectVO.setTotalOrdersCnt(totalOrdersCnt);
			dto.addToResultList(iObjectVO);
			dto.setSuccess(true);
		} catch (Exception e) {
			e.printStackTrace();
			dto.setErrorMSG(MyErrorMsgConstants.FAILED_TO_QUERY_ORDERS);
			dto.setSuccess(false);
		}
		return dto;
	}
	
	public IOPResultDto<IObjectVO> findByState(Integer orderState, Integer pageNum, Integer pageSize) {
		IOPResultDto<IObjectVO> dto = new IOPResultDto<IObjectVO>();
		try {
			List<Orders> ordersList = iOrdersDao.findByState(orderState, pageNum, pageSize);
			int totalOrdersCnt = iOrdersDao.findTotalOrdersCntByOrderState(orderState);
			List<OrdersVO> ordersVOList = new ArrayList<OrdersVO>();
			OrdersVO ordersVO = null;
			Goods goods = null;
			GoodsVO goodsVO = null;
			City city = null;
			CityVO cityVO = null;
			User user = null;
			UserVO userVO = null;
			for (Orders orders : ordersList) {
				goods = iGoodsDao.findById(orders.getGoods().getGoodsId());
				city = iCityDao.findById(orders.getCity().getCityId());
				user = iUserDao.findById(orders.getUser().getUserId());
				goodsVO = new GoodsVO();
				BeanUtils.copyProperties(goods, goodsVO);
				cityVO = new CityVO();
				BeanUtils.copyProperties(city, cityVO);
				userVO = new UserVO();
				BeanUtils.copyProperties(user, userVO);
				userVO.setUserPassword("");
				ordersVO = new OrdersVO();
				BeanUtils.copyProperties(orders, ordersVO);
				
				ordersVO.setGoodsVO(goodsVO);
				ordersVO.setCityVO(cityVO);
				ordersVO.setUserVO(userVO);
				ordersVOList.add(ordersVO);
			}
			IObjectVO iObjectVO = new IObjectVO();
			iObjectVO.setOrdersVOList(ordersVOList);
			iObjectVO.setTotalOrdersCnt(totalOrdersCnt);
			dto.addToResultList(iObjectVO);
			dto.setSuccess(true);
		} catch (Exception e) {
			e.printStackTrace();
			dto.setErrorMSG(MyErrorMsgConstants.FAILED_TO_QUERY_ORDERS);
			dto.setSuccess(false);
		}
		return dto;
	}
	
	public IOPResultDto<IObjectVO> findByOrderId(Integer orderId) {
		IOPResultDto<IObjectVO> dto = new IOPResultDto<IObjectVO>();
		try {
			Orders order = iOrdersDao.findById(orderId);
			List<OrdersVO> ordersVOList = new ArrayList<OrdersVO>();
			OrdersVO ordersVO = null;
			Goods goods = null;
			GoodsVO goodsVO = null;
			City city = null;
			CityVO cityVO = null;
			User user = null;
			UserVO userVO = null;
			Comment comment = null;
			if (order != null) {
				goods = iGoodsDao.findById(order.getGoods().getGoodsId());
				city = iCityDao.findById(order.getCity().getCityId());
				user = iUserDao.findById(order.getUser().getUserId());
				HashMap<String, Object> map = new HashMap<String, Object>();
				map.put("orders", order);
				List<Comment> commentList = iCommentDao.findByExample(map);
				if(commentList != null && commentList.size() > 0) {
					comment = commentList.get(0);
				}
				goodsVO = new GoodsVO();
				BeanUtils.copyProperties(goods, goodsVO);
				cityVO = new CityVO();
				BeanUtils.copyProperties(city, cityVO);
				userVO = new UserVO();
				BeanUtils.copyProperties(user, userVO);
				userVO.setUserPassword("");
				ordersVO = new OrdersVO();
				BeanUtils.copyProperties(order, ordersVO);
				
				ordersVO.setGoodsVO(goodsVO);
				ordersVO.setCityVO(cityVO);
				ordersVO.setUserVO(userVO);
				if(comment != null) {
					ordersVO.setOrdersComment(comment.getComment());
				}
				
				ordersVOList.add(ordersVO);
				
				IObjectVO iObjectVO = new IObjectVO();
				iObjectVO.setOrdersVOList(ordersVOList);
				dto.addToResultList(iObjectVO);
				dto.setSuccess(true);
			}else {
				dto.setErrorMSG(MyErrorMsgConstants.FAILED_TO_QUERY_ORDERS);
				dto.setSuccess(false);
			}
			return dto;
		} catch (Exception e) {
			e.printStackTrace();
			dto.setErrorMSG(MyErrorMsgConstants.FAILED_TO_QUERY_ORDERS);
			dto.setSuccess(false);
			return dto;
		}
	}
	
	public IOPResultDto<IObjectVO> updateOrderState(Integer orderId, Integer newState) {
		IOPResultDto<IObjectVO> dto = new IOPResultDto<IObjectVO>();
		try {
			Orders orders = iOrdersDao.findById(orderId);
			if(orders == null) {
				dto.setErrorMSG(MyErrorMsgConstants.NOT_EXIST_DATA_FOR_OPERATE);
				dto.setSuccess(false);
				return dto;
			}
			if(newState <= orders.getOrderState()) {
				dto.setErrorMSG(MyErrorMsgConstants.ERROR_OPERATE_FOR_ORDER_STATE_ILLEGAL);
				dto.setSuccess(false);
				return dto;
			}
			orders.setOrderState(newState);
			orders.setDoneDate(new Date());
			iOrdersDao.update(orders);
			dto.setSuccess(true);
			return dto;
		} catch (Exception e) {
			e.printStackTrace();
			dto.setErrorMSG(MyErrorMsgConstants.FAILED_TO_UPDATE_OPERATE);
			dto.setSuccess(false);
			return dto;
		}
	}
	public IOPResultDto<IObjectVO> updateOrderStateC(Integer userId, Integer orderId, Integer newState, String orderComment) {
		IOPResultDto<IObjectVO> dto = new IOPResultDto<IObjectVO>();
		try {
			Orders orders = iOrdersDao.findById(orderId);
			if(orders == null) {
				dto.setErrorMSG(MyErrorMsgConstants.NOT_EXIST_DATA_FOR_OPERATE);
				dto.setSuccess(false);
				return dto;
			}
			//增加对订单操作者身份的验证
			if(orders.getUser().getUserId() != userId) {
				dto.setErrorMSG(MyErrorMsgConstants.ERR_ILLEGAL_OPERATOR);
				dto.setSuccess(false);
				return dto;
			}
			if(newState <= orders.getOrderState()) {
				dto.setErrorMSG(MyErrorMsgConstants.ERROR_OPERATE_FOR_ORDER_STATE_ILLEGAL);
				dto.setSuccess(false);
				return dto;
			}

			orders.setOrderState(newState);
			orders.setDoneDate(new Date());
			iOrdersDao.update(orders);
			
			 //此处对评价做存储
			Comment comment = new Comment();
			comment.setCommentId(0);
			comment.setComment(orderComment);
			Goods goods = iGoodsDao.findById(orders.getGoods().getGoodsId());
			comment.setGoods(goods);
			comment.setOrders(orders);
			comment.setCreateDate(new Date());
			iCommentDao.add(comment);
			
			dto.setSuccess(true);
			return dto;
		} catch (Exception e) {
			e.printStackTrace();
			dto.setErrorMSG(MyErrorMsgConstants.FAILED_TO_UPDATE_OPERATE);
			dto.setSuccess(false);
			return dto;
		}
	}
	
}
